import { defineStore } from "pinia";
import { store } from "@/store";
import type { Icon } from "types/editor";
import { EditorActiveType } from "@/components/TopologyEditor/constant";
import type { Pen, Rect } from "@meta2d/core";

type commonResult<T> = {
  code: number;
  msg: string;
  result: T;
};

type requestCache = {
  responseData: commonResult<any>,
  expirationTime: number,
}
export const useTopologyEditorStore = defineStore("topology-editor", {
  state: () => ({
    editorScale: 100,
    oftenIcons: [] as Icon[],
    editorActiveType: EditorActiveType.CanvasActive,
    currentPen: {} as Pen,
    currentPenRect: {} as Rect,
    currentPenLength: 0,
    currentPens: [] as Pen[],
    requestCache: new Map() as Map<string, requestCache>,
    editTemplate: null
  }),
  actions: {
    setEditorScale(value: number) {
      this.editorScale = value;
    },
    setEditorActiveType(type: EditorActiveType) {
      this.editorActiveType = type;
    },
    setCurrentPen(value: Pen) {
      this.currentPen = value;
    },
    setCurrentPens(value: Pen[]) {
      this.currentPens = value;
    },
    setCurrentPenLength(length: number) {
      this.currentPenLength = length;
    },
    setCurrentPenRect(value: Rect) {
      this.currentPenRect = value;
    },
    addOftenIcon(icon: Icon) {
      const iconArr = this.oftenIcons;
      const index = iconArr.findIndex(item => {
        return item.name === icon.name;
      });
      if (index > -1) {
        iconArr.splice(index, 1);
      }
      const newLength = iconArr.unshift(icon);
      if (newLength > 8) {
        iconArr.splice(8, 1);
      }
    },
    getRequestCache(func: (params?: object) => Promise<commonResult<any>>, params?: object) {
      let key = func.toString() + JSON.stringify(params)
      return new Promise<commonResult<any>>((resolve, reject) => {
        if (this.requestCache.has(key)) {
          let now = Date.now()
          if (this.requestCache.get(key).expirationTime <= now) {
            this.requestCache.set(key, {
              expirationTime: Date.now() + 1000,
              responseData: null
            })
            func(params).then(res => {
              this.requestCache.set(key, {
                expirationTime: Date.now() + 1000,
                responseData: res
              })
              resolve(res)
            }).catch(rej => {
              reject(rej)
            })
          } else {
            if (this.requestCache.get(key).responseData == null) {
              setTimeout(() => {
                this.getRequestCache(func, params).then(res => {
                  resolve(res)
                }).catch(rej => {
                  reject(rej)
                })
              }, this.requestCache.get(key).expirationTime - now)
            } else {
              resolve(this.requestCache.get(key).responseData)
            }
          }
        } else {
          this.requestCache.set(key, {
            expirationTime: Date.now() + 1000,
            responseData: null
          })
          func(params).then(res => {
            this.requestCache.set(key, {
              expirationTime: Date.now() + 1000,
              responseData: res
            })
            resolve(res)
          }).catch(rej => {
            reject(rej)
          })
        }
      })
    }
  }
});


export const useTopologyEditorStoreOutside = () => useTopologyEditorStore(store);
